package cn.uncode.baas.server.resource;


import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import cn.uncode.baas.server.acl.token.AccessToken;
import cn.uncode.baas.server.cache.SystemCache;
import cn.uncode.baas.server.constant.Resource;
import cn.uncode.baas.server.database.DBContextHolder;
import cn.uncode.baas.server.dto.RestUser;
import cn.uncode.baas.server.exception.ValidateException;
import cn.uncode.baas.server.internal.context.RestContextManager;
import cn.uncode.baas.server.internal.message.Messages;
import cn.uncode.baas.server.service.IUserService;
import cn.uncode.baas.server.utils.DataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

/**
 * 通用rest接口
 * @author ywj
 *
 */
@Controller
public class UserResource extends BaseResource{
	
	
    @Autowired
    private IUserService userService;
    
    /**
     * 
     * @param bucket
     * @param request
     * @return
     * @throws ValidateException
     * @throws Exception
     */
    
    @RequestMapping(value = "/{bucket}/login", method = RequestMethod.POST, consumes = "application/json")
    public @ResponseBody
    ResponseEntity<Object> login(@PathVariable("bucket") String bucket, @RequestBody Map<String, Object> request) throws ValidateException, Exception {
    	if(request == null || request.size() == 0){
            return new ResponseEntity<Object>(HttpStatus.BAD_REQUEST);
        }
        Map<String, Object> maps = convertWebRequest(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
        String accessToken = userService.login(maps);
        if(StringUtils.isEmpty(accessToken)){
        	return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
        }
        return new ResponseEntity<Object>(accessToken, HttpStatus.OK);
    }

    /**
     * {"username":"adf","password":"asdfas","link":"http://www.1233.comm"}
     * @param bucket
     * @param request
     * @return
     * @throws ValidateException
     * @throws Exception
     */
    @RequestMapping(value = "/{bucket}/signup", method = RequestMethod.POST, consumes = "application/json")
    public ResponseEntity<Object> insert(@PathVariable("bucket") String bucket, @RequestBody Map<String, Object> request) throws ValidateException, Exception {
        if(request == null || request.size() == 0){
            return new ResponseEntity<Object>(HttpStatus.BAD_REQUEST);
        }
        Map<String, Object> maps = convertWebRequest(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
        String result = userService.signup(maps);
       
        if(StringUtils.isEmpty(result)){
        	return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("id", result);
        return new ResponseEntity<Object>(resultMap, HttpStatus.OK);
    }
    
    
    
    @RequestMapping(value = "/{bucket}/logout", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public @ResponseBody
    ResponseEntity<Object> logout(@PathVariable("bucket") String bucket) {
    	Map<String, Object> params = new HashMap<String, Object>();
    	AccessToken  token = RestContextManager.getContext().getToken();
    	if(null != token){
    		params.put(Resource.REQ_ACCESS_TOKEN, token.getValue());
            DBContextHolder.setDbType(bucket);
            userService.logout(params);
    	}
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    
    @RequestMapping(value = "/{bucket}/users", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public @ResponseBody
    ResponseEntity<Object> users(@PathVariable("bucket") String bucket, WebRequest request) {
    	Map<String, Object> maps = DataUtils.convertWebRequest2Map(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
        List<Map<String, Object>> result = userService.selectUsers(maps);
        if(null != result){
        	return new ResponseEntity<Object>(result, HttpStatus.OK);
        }
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    @RequestMapping(value = "/token/{token}", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public @ResponseBody
    ResponseEntity<Object> token(@PathVariable("token") String token) {
    	Map<String, Object> params = new HashMap<String, Object>();
    	params.put(Resource.REQ_ACCESS_TOKEN, token);
        Map<String, Object> result = userService.getToken(params);
        if(null != result){
        	return new ResponseEntity<Object>(result, HttpStatus.OK);
        }
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    @RequestMapping(value = "/{bucket}/user", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public @ResponseBody
    ResponseEntity<Object> user(@PathVariable("bucket") String bucket, WebRequest request) {
    	Map<String, Object> params = DataUtils.convertWebRequest2Map(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
        Map<String, Object> result = userService.getUser(params);
        if(null != result){
        	return new ResponseEntity<Object>(result, HttpStatus.OK);
        }
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    @RequestMapping(value = "/{bucket}/user", method = RequestMethod.POST, consumes = "application/json")
    public @ResponseBody
    ResponseEntity<Object> userUpdate(@PathVariable("bucket") String bucket, @RequestBody Map<String, Object> request) throws ValidateException, Exception {
    	Map<String, Object> params = convertWebRequest(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
        userService.update(params);
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    
    /**
     * {"id":1,["username":"12365241",]"password":"123654","oldPassword":"654321","code":"252365"}
     * 
     * @param bucket
     * @param request
     * @return
     * @throws Exception 
     * @throws ValidateException 
     */
    @RequestMapping(value = "/{bucket}/resetpass", method = RequestMethod.POST, consumes = "application/json")
    public @ResponseBody
    ResponseEntity<Object> resetpass(@PathVariable("bucket") String bucket, @RequestBody Map<String, Object> request) throws ValidateException, Exception {
    	if(request == null || request.size() == 0){
            return new ResponseEntity<Object>(HttpStatus.BAD_REQUEST);
        }
        Map<String, Object> maps = convertWebRequest(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
    	userService.update(maps);
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    /**
     * {"id":1,["username":"12365241",]"code":"25365"}
     * 
     * @param bucket
     * @param request
     * @return
     * @throws Exception 
     * @throws ValidateException 
     */
    @RequestMapping(value = "/{bucket}/activate", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public @ResponseBody
    ResponseEntity<Object> activate(@PathVariable("bucket") String bucket, WebRequest request) throws ValidateException, Exception {
        Map<String, Object> maps = DataUtils.convertWebRequest2Map(request);
        if(maps == null || maps.size() == 0){
            return new ResponseEntity<Object>(HttpStatus.BAD_REQUEST);
        }
        RestUser user = SystemCache.getRestUser(bucket);
        if(StringUtils.isNotEmpty(user.getStatusField())){
        	maps.put(user.getStatusField(), Resource.REST_USER_STATUS_VALID);
        }else{
        	maps.put(Resource.REST_USER_STATUS, Resource.REST_USER_STATUS_VALID);
        }
        maps.put(Resource.REST_USER_EMAIL_TYPE, IUserService.EMAIL_ACTIVATE);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
    	userService.update(maps);
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    /**
     * {"id":1,["username":"12365241",]"link":"http://123.html","emailType":"resetpass/activate"}
     * 
     * @param bucket
     * @param request
     * @return
     */
    @RequestMapping(value = "/{bucket}/mail", method = RequestMethod.POST, consumes = "application/json")
    public @ResponseBody
    ResponseEntity<Object> sendMail(@PathVariable("bucket") String bucket, @RequestBody Map<String, Object> request) {
    	if(request == null || request.size() == 0){
            return new ResponseEntity<Object>(HttpStatus.BAD_REQUEST);
        }
        Map<String, Object> maps = convertWebRequest(request);
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
    	userService.sendMailAgain(maps);
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }
    
    @RequestMapping(value = "/{bucket}/checkname", method = RequestMethod.POST, consumes = "application/json")
    public @ResponseBody
    ResponseEntity<Object> checkname(@PathVariable("bucket") String bucket, @RequestBody Map<String, Object> request) {
    	if(request == null || request.size() == 0){
            return new ResponseEntity<Object>(HttpStatus.BAD_REQUEST);
        }
        Map<String, Object> maps = convertWebRequest(request);
        
        RestUser user = SystemCache.getRestUser(bucket);
        if(null == user){
        	throw new ValidateException(Messages.getString("RuntimeError.13"));
        }
        maps.put("table", user.getTableName());
        DBContextHolder.setDbType(bucket);
        RestContextManager.initBucket(bucket);
    	userService.checkUsername(maps);
        return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
    }

    /**
     * 剔除公用参数
     * @param request
     * @return
     */
    private Map<String, Object> convertWebRequest(Map<String, Object> request){
    	if(request.containsKey(Resource.REQ_ACCESS_TOKEN)){
    		request.remove(Resource.REQ_ACCESS_TOKEN);
        }
    	return request;
    }
    
}
